#ifndef WINDOW_H
#define WINDOW_H

#include <QHash>
#include <QVector>
#include <QVariant>
#include <functional>

#include "element.h"

class WindowManager;

class QLUISHARED_EXPORT Window : public Element
{
    Q_OBJECT
public:
    Window();


    /*********************************************************************
     *                    Copying
     * *******************************************************************/
public:
    virtual bool copyFrom(const Element *e) override;
    virtual Element *clone() const override;


    /*********************************************************************
     *                    Position & Size
     * *******************************************************************/
public:
    virtual QRect sizeHint() const override;

private:
    QRect size_hint_;

    /*********************************************************************
     *                    Elements
     * *******************************************************************/
public:
    bool addElement(Element *e, bool setParent=true);
    Element *element(const QString& name) const;

    template<class T>
    T *element(const QString& name) const{
        return qobject_cast<T*>(element(name));
    }

private:
    QHash<QString, Element*> elements_;
    QHash<Element*, Element*> anymous_elements_;
    QHash<int, QVector<Element*>> key_elements_;
    QList<Element*> need_focus_elements_;

    /*********************************************************************
     *                    Window
     * *******************************************************************/
public:
    Q_INVOKABLE void switchWindowTo(quint32 id);


    /*********************************************************************
     *                    paint
     * *******************************************************************/
public:
    virtual void paintEvent() override;
    virtual void hideEvent() override;


    /*********************************************************************
     *                    Data
     * *******************************************************************/
public:
    void setExternData(const QString &name, const QVariant &data);
    QVariant externData(const QString &name);

private:
    QHash<QString, QVariant> extern_data_;

    /*********************************************************************
     *                    Event
     * *******************************************************************/
public:
    typedef std::function<void(void)> Hook;

    void addPreLoad(const Hook &h);
    void preLoad(WindowManager *wm);
    void addPostLoad(const Hook &h);
    void postLoad(WindowManager *wm);

    QList<int> bindingKeysInWindow() const;
    bool isBindKeyInWindow(int key) const;

public slots:
    /**
     * @brief slot for signal keyboardEvent from WindowManager
     * @param key
     * @param value
     */
    void onKeyEvent(int key, int value);

    /**
     * @brief slot for signal moveEvent from WindowManager
     * @param direction
     */
    void onMoveEvent(MoveDirection direction);

private:
    QVector<Hook> pre_load_fun_;
    QVector<Hook> post_load_fun_;
};

#endif // WINDOW_H
